home *** CD-ROM | disk | FTP | other *** search
/ MacWorld 1995 November / Macworld Nov ’95.toast / Developers / Flex 2.5.2 / flex-2.5.2 / scan.l < prev    next >
Encoding:
Text File  |  1995-06-27  |  14.9 KB  |  710 lines  |  [TEXT/MPS ]

  1. /* scan.l - scanner for flex input */
  2.  
  3. %{
  4. /*-
  5.  * Copyright (c) 1990 The Regents of the University of California.
  6.  * All rights reserved.
  7.  *
  8.  * This code is derived from software contributed to Berkeley by
  9.  * Vern Paxson.
  10.  * 
  11.  * The United States Government has rights in this work pursuant
  12.  * to contract no. DE-AC03-76SF00098 between the United States
  13.  * Department of Energy and the University of California.
  14.  *
  15.  * Redistribution and use in source and binary forms are permitted provided
  16.  * that: (1) source distributions retain this entire copyright notice and
  17.  * comment, and (2) distributions including binaries display the following
  18.  * acknowledgement:  ``This product includes software developed by the
  19.  * University of California, Berkeley and its contributors'' in the
  20.  * documentation or other materials provided with the distribution and in
  21.  * all advertising materials mentioning features or use of this software.
  22.  * Neither the name of the University nor the names of its contributors may
  23.  * be used to endorse or promote products derived from this software without
  24.  * specific prior written permission.
  25.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
  26.  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  27.  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  28.  */
  29.  
  30. /* $Header: /home/daffy/u0/vern/flex/RCS/scan.l,v 2.56 95/04/24 12:17:19 vern Exp $ */
  31.  
  32. #include "flexdef.h"
  33. #include "parse.h"
  34.  
  35. #define ACTION_ECHO add_action( yytext )
  36. #define ACTION_IFDEF(def, should_define) \
  37.     { \
  38.     if ( should_define ) \
  39.         action_define( def, 1 ); \
  40.     }
  41.  
  42. #define MARK_END_OF_PROLOG mark_prolog();
  43.  
  44. #define YY_DECL \
  45.     int flexscan()
  46.  
  47. #define RETURNCHAR \
  48.     yylval = (unsigned char) yytext[0]; \
  49.     return CHAR;
  50.  
  51. #define RETURNNAME \
  52.     strcpy( nmstr, yytext ); \
  53.     return NAME;
  54.  
  55. #define PUT_BACK_STRING(str, start) \
  56.     for ( i = strlen( str ) - 1; i >= start; --i ) \
  57.         unput((str)[i])
  58.  
  59. #define CHECK_REJECT(str) \
  60.     if ( all_upper( str ) ) \
  61.         reject = true;
  62.  
  63. #define CHECK_YYMORE(str) \
  64.     if ( all_lower( str ) ) \
  65.         yymore_used = true;
  66. %}
  67.  
  68. %option caseless nodefault outfile="scan.c" stack noyy_top_state
  69. %option nostdinit
  70.  
  71. %x SECT2 SECT2PROLOG SECT3 CODEBLOCK PICKUPDEF SC CARETISBOL NUM QUOTE
  72. %x FIRSTCCL CCL ACTION RECOVER COMMENT ACTION_STRING PERCENT_BRACE_ACTION
  73. %x OPTION LINEDIR
  74.  
  75. WS        [[:blank:]]+
  76. OPTWS        [[:blank:]]*
  77. NOT_WS        [^[:blank:]\n]
  78.  
  79. /*NL        \r?\n    changed to just \n by CEH */
  80. NL        \n
  81.  
  82. NAME        ([[:alpha:]_][[:alnum:]_-]*)
  83. NOT_NAME    [^[:alpha:]_*\n]+
  84.  
  85. SCNAME        {NAME}
  86.  
  87. ESCSEQ        (\\([^\n]|[0-7]{1,3}|x[[:xdigit:]]{1,2}))
  88.  
  89. FIRST_CCL_CHAR    ([^\\\n]|{ESCSEQ})
  90. CCL_CHAR    ([^\\\n\]]|{ESCSEQ})
  91. CCL_EXPR    ("[:"[[:alpha:]]+":]")
  92.  
  93. LEXOPT        [aceknopr]
  94.  
  95. %%
  96.     static int bracelevel, didadef, indented_code;
  97.     static int doing_rule_action = false;
  98.     static int option_sense;
  99.  
  100.     int doing_codeblock = false;
  101.     int i;
  102.     Char nmdef[MAXLINE] /* CEH , myesc() */;
  103.  
  104.  
  105. <INITIAL>{
  106.     ^{WS}        indented_code = true; BEGIN(CODEBLOCK);
  107.     ^"/*"        ACTION_ECHO; yy_push_state( COMMENT );
  108.     ^#{OPTWS}line{WS}    yy_push_state( LINEDIR );
  109.     ^"%s"{NAME}?    return SCDECL;
  110.     ^"%x"{NAME}?    return XSCDECL;
  111.     ^"%{".*{NL}    {
  112.             ++linenum;
  113.             line_directive_out( (FILE *) 0, 1 );
  114.             indented_code = false;
  115.             BEGIN(CODEBLOCK);
  116.             }
  117.  
  118.     {WS}        /* discard */
  119.  
  120.     ^"%%".*        {
  121.             sectnum = 2;
  122.             bracelevel = 0;
  123.             mark_defs1();
  124.             line_directive_out( (FILE *) 0, 1 );
  125.             BEGIN(SECT2PROLOG);
  126.             return SECTEND;
  127.             }
  128.  
  129.     ^"%pointer".*{NL}    yytext_is_array = false; ++linenum;
  130.     ^"%array".*{NL}        yytext_is_array = true; ++linenum;
  131.  
  132.     ^"%option"    BEGIN(OPTION); return OPTION_OP;
  133.  
  134.     ^"%"{LEXOPT}{OPTWS}[[:digit:]]*{OPTWS}{NL}    ++linenum; /* ignore */
  135.     ^"%"{LEXOPT}{WS}.*{NL}    ++linenum;    /* ignore */
  136.  
  137.     ^"%"[^sxaceknopr{}].*    synerr( _( "unrecognized '%' directive" ) );
  138.  
  139.     ^{NAME}        {
  140.             strcpy( nmstr, yytext );
  141.             didadef = false;
  142.             BEGIN(PICKUPDEF);
  143.             }
  144.  
  145.     {SCNAME}    RETURNNAME;
  146.     ^{OPTWS}{NL}    ++linenum; /* allows blank lines in section 1 */
  147.     {OPTWS}{NL}    ACTION_ECHO; ++linenum; /* maybe end of comment line */
  148. }
  149.  
  150.  
  151. <COMMENT>{
  152.     "*/"        ACTION_ECHO; yy_pop_state();
  153.     "*"        ACTION_ECHO;
  154.     [^*\n]+        ACTION_ECHO;
  155.     [^*\n]*{NL}    ++linenum; ACTION_ECHO;
  156. }
  157.  
  158. <LINEDIR>{
  159.     \n        yy_pop_state();
  160.     [[:digit:]]+    linenum = myctoi( yytext );
  161.  
  162.     \"[^"\n]*\"    {
  163.             flex_free( (void *) infilename );
  164.             infilename = copy_string( yytext + 1 );
  165.             infilename[strlen( infilename ) - 1] = '\0';
  166.             }
  167.     .        /* ignore spurious characters */
  168. }
  169.  
  170. <CODEBLOCK>{
  171.     ^"%}".*{NL}    ++linenum; BEGIN(INITIAL);
  172.  
  173.     {NAME}|{NOT_NAME}|.    ACTION_ECHO;
  174.  
  175.     {NL}        {
  176.             ++linenum;
  177.             ACTION_ECHO;
  178.             if ( indented_code )
  179.                 BEGIN(INITIAL);
  180.             }
  181. }
  182.  
  183.  
  184. <PICKUPDEF>{
  185.     {WS}        /* separates name and definition */
  186.  
  187.     {NOT_WS}.*    {
  188.             strcpy( (char *) nmdef, yytext );
  189.  
  190.             /* Skip trailing whitespace. */
  191.             for ( i = strlen( (char *) nmdef ) - 1;
  192.                   i >= 0 && (nmdef[i] == ' ' || nmdef[i] == '\t');
  193.                   --i )
  194.                 ;
  195.  
  196.             nmdef[i + 1] = '\0';
  197.  
  198.             ndinstal( nmstr, nmdef );
  199.             didadef = true;
  200.             }
  201.  
  202.     {NL}        {
  203.             if ( ! didadef )
  204.                 synerr( _( "incomplete name definition" ) );
  205.             BEGIN(INITIAL);
  206.             ++linenum;
  207.             }
  208. }
  209.  
  210.  
  211. <OPTION>{
  212.     {NL}        ++linenum; BEGIN(INITIAL);
  213.     {WS}        option_sense = true;
  214.  
  215.     "="        return '=';
  216.  
  217.     no        option_sense = ! option_sense;
  218.  
  219.     7bit        csize = option_sense ? 128 : 256;
  220.     8bit        csize = option_sense ? 256 : 128;
  221.  
  222.     align        long_align = option_sense;
  223.     always-interactive    {
  224.             action_define( "YY_ALWAYS_INTERACTIVE", option_sense );
  225.             }
  226.     array        yytext_is_array = option_sense;
  227.     backup        backing_up_report = option_sense;
  228.     batch        interactive = ! option_sense;
  229.     "c++"        C_plus_plus = option_sense;
  230.     caseful|case-sensitive        caseins = ! option_sense;
  231.     caseless|case-insensitive    caseins = option_sense;
  232.     debug        ddebug = option_sense;
  233.     default        spprdflt = ! option_sense;
  234.     ecs        useecs = option_sense;
  235.     fast        {
  236.             useecs = usemecs = false;
  237.             use_read = fullspd = true;
  238.             }
  239.     full        {
  240.             useecs = usemecs = false;
  241.             use_read = fulltbl = true;
  242.             }
  243.     input        ACTION_IFDEF("YY_NO_INPUT", ! option_sense);
  244.     interactive    interactive = option_sense;
  245.     lex-compat    lex_compat = option_sense;
  246.     main        {
  247.             action_define( "YY_MAIN", option_sense );
  248.             do_yywrap = ! option_sense;
  249.             }
  250.     meta-ecs    usemecs = option_sense;
  251.     never-interactive    {
  252.             action_define( "YY_NEVER_INTERACTIVE", option_sense );
  253.             }
  254.     perf-report    performance_report += option_sense ? 1 : -1;
  255.     pointer        yytext_is_array = ! option_sense;
  256.     read        use_read = option_sense;
  257.     reject        reject_really_used = option_sense;
  258.     stack        action_define( "YY_STACK_USED", option_sense );
  259.     stdinit        do_stdinit = option_sense;
  260.     stdout        use_stdout = option_sense;
  261.     unput        ACTION_IFDEF("YY_NO_UNPUT", ! option_sense);
  262.     verbose        printstats = option_sense;
  263.     warn        nowarn = ! option_sense;
  264.     yylineno    do_yylineno = option_sense;
  265.     yymore        yymore_really_used = option_sense;
  266.     yywrap        do_yywrap = option_sense;
  267.  
  268.     yy_push_state    ACTION_IFDEF("YY_NO_PUSH_STATE", ! option_sense);
  269.     yy_pop_state    ACTION_IFDEF("YY_NO_POP_STATE", ! option_sense);
  270.     yy_top_state    ACTION_IFDEF("YY_NO_TOP_STATE", ! option_sense);
  271.  
  272.     yy_scan_buffer    ACTION_IFDEF("YY_NO_SCAN_BUFFER", ! option_sense);
  273.     yy_scan_bytes    ACTION_IFDEF("YY_NO_SCAN_BYTES", ! option_sense);
  274.     yy_scan_string    ACTION_IFDEF("YY_NO_SCAN_STRING", ! option_sense);
  275.  
  276.     outfile        return OPT_OUTFILE;
  277.     prefix        return OPT_PREFIX;
  278.     yyclass        return OPT_YYCLASS;
  279.  
  280.     \"[^"\n]*\"    {
  281.             strcpy( nmstr, yytext + 1 );
  282.             nmstr[strlen( nmstr ) - 1] = '\0';
  283.             return NAME;
  284.             }
  285.  
  286.     (([a-mo-z]|n[a-np-z])[[:alpha:]\-+]*)|.    {
  287.             format_synerr( _( "unrecognized %%option: %s" ),
  288.                 yytext );
  289.             BEGIN(RECOVER);
  290.             }
  291. }
  292.  
  293. <RECOVER>.*{NL}        ++linenum; BEGIN(INITIAL);
  294.  
  295.  
  296. <SECT2PROLOG>{
  297.     ^"%{".*    ++bracelevel; yyless( 2 );    /* eat only %{ */
  298.     ^"%}".*    --bracelevel; yyless( 2 );    /* eat only %} */
  299.  
  300.     ^{WS}.*    ACTION_ECHO;    /* indented code in prolog */
  301.  
  302.     ^{NOT_WS}.*    {    /* non-indented code */
  303.             if ( bracelevel <= 0 )
  304.                 { /* not in %{ ... %} */
  305.                 yyless( 0 );    /* put it all back */
  306.                 yy_set_bol( 1 );
  307.                 mark_prolog();
  308.                 BEGIN(SECT2);
  309.                 }
  310.             else
  311.                 ACTION_ECHO;
  312.             }
  313.  
  314.     .*        ACTION_ECHO;
  315.     {NL}    ++linenum; ACTION_ECHO;
  316.  
  317.     <<EOF>>        {
  318.             mark_prolog();
  319.             sectnum = 0;
  320.             yyterminate(); /* to stop the parser */
  321.             }
  322. }
  323.  
  324. <SECT2>{
  325.     ^{OPTWS}{NL}    ++linenum; /* allow blank lines in section 2 */
  326.  
  327.     ^{OPTWS}"%{"    {
  328.             indented_code = false;
  329.             doing_codeblock = true;
  330.             bracelevel = 1;
  331.             BEGIN(PERCENT_BRACE_ACTION);
  332.             }
  333.  
  334.     ^{OPTWS}"<"    BEGIN(SC); return '<';
  335.     ^{OPTWS}"^"    return '^';
  336.     \"        BEGIN(QUOTE); return '"';
  337.     "{"/[[:digit:]]    BEGIN(NUM); return '{';
  338.     "$"/([[:blank:]]|{NL})    return '$';
  339.  
  340.     {WS}"%{"        {
  341.             bracelevel = 1;
  342.             BEGIN(PERCENT_BRACE_ACTION);
  343.  
  344.             if ( in_rule )
  345.                 {
  346.                 doing_rule_action = true;
  347.                 in_rule = false;
  348.                 return '\n';
  349.                 }
  350.             }
  351.     {WS}"|".*{NL}    continued_action = true; ++linenum; return '\n';
  352.  
  353.     ^{WS}"/*"    {
  354.             yyless( yyleng - 2 );    /* put back '/', '*' */
  355.             bracelevel = 0;
  356.             continued_action = false;
  357.             BEGIN(ACTION);
  358.             }
  359.  
  360.     ^{WS}        /* allow indented rules */
  361.  
  362.     {WS}        {
  363.             /* This rule is separate from the one below because
  364.              * otherwise we get variable trailing context, so
  365.              * we can't build the scanner using -{f,F}.
  366.              */
  367.             bracelevel = 0;
  368.             continued_action = false;
  369.             BEGIN(ACTION);
  370.  
  371.             if ( in_rule )
  372.                 {
  373.                 doing_rule_action = true;
  374.                 in_rule = false;
  375.                 return '\n';
  376.                 }
  377.             }
  378.  
  379.     {OPTWS}{NL}    {
  380.             bracelevel = 0;
  381.             continued_action = false;
  382.             BEGIN(ACTION);
  383.             unput( '\n' );    /* so <ACTION> sees it */
  384.  
  385.             if ( in_rule )
  386.                 {
  387.                 doing_rule_action = true;
  388.                 in_rule = false;
  389.                 return '\n';
  390.                 }
  391.             }
  392.  
  393.     ^{OPTWS}"<<EOF>>"    |
  394.     "<<EOF>>"    return EOF_OP;
  395.  
  396.     ^"%%".*        {
  397.             sectnum = 3;
  398.             BEGIN(SECT3);
  399.             yyterminate(); /* to stop the parser */
  400.             }
  401.  
  402.     "["({FIRST_CCL_CHAR}|{CCL_EXPR})({CCL_CHAR}|{CCL_EXPR})*    {
  403.             int cclval;
  404.  
  405.             strcpy( nmstr, yytext );
  406.  
  407.             /* Check to see if we've already encountered this
  408.              * ccl.
  409.              */
  410.             if ( (cclval = ccllookup( (Char *) nmstr )) != 0 )
  411.                 {
  412.                 if ( yyinput() != ']' ) /* CEH */
  413.                     synerr( _( "bad character class" ) );
  414.  
  415.                 yylval = cclval;
  416.                 ++cclreuse;
  417.                 return PREVCCL;
  418.                 }
  419.             else
  420.                 {
  421.                 /* We fudge a bit.  We know that this ccl will
  422.                  * soon be numbered as lastccl + 1 by cclinit.
  423.                  */
  424.                 cclinstal( (Char *) nmstr, lastccl + 1 );
  425.  
  426.                 /* Push back everything but the leading bracket
  427.                  * so the ccl can be rescanned.
  428.                  */
  429.                 yyless( 1 );
  430.  
  431.                 BEGIN(FIRSTCCL);
  432.                 return '[';
  433.                 }
  434.             }
  435.  
  436.     "{"{NAME}"}"    {
  437.             register Char *nmdefptr;
  438.     /* CEH        Char *ndlookup(); */
  439.  
  440.             strcpy( nmstr, yytext + 1 );
  441.             nmstr[yyleng - 2] = '\0';  /* chop trailing brace */
  442.  
  443.             if ( (nmdefptr = ndlookup( nmstr )) == 0 )
  444.                 format_synerr(
  445.                     _( "undefined definition {%s}" ),
  446.                         nmstr );
  447.  
  448.             else
  449.                 { /* push back name surrounded by ()'s */
  450.                 int len = strlen( (char *) nmdefptr );
  451.  
  452.                 if ( lex_compat || nmdefptr[0] == '^' ||
  453.                      (len > 0 && nmdefptr[len - 1] == '$') )
  454.                     { /* don't use ()'s after all */
  455.                     PUT_BACK_STRING((char *) nmdefptr, 0);
  456.  
  457.                     if ( nmdefptr[0] == '^' )
  458.                         BEGIN(CARETISBOL);
  459.                     }
  460.  
  461.                 else
  462.                     {
  463.                     unput(')');
  464.                     PUT_BACK_STRING((char *) nmdefptr, 0);
  465.                     unput('(');
  466.                     }
  467.                 }
  468.             }
  469.  
  470.     [/|*+?.(){}]    return (unsigned char) yytext[0];
  471.     .        RETURNCHAR;
  472. }
  473.  
  474.  
  475. <SC>{
  476.     [,*]        return (unsigned char) yytext[0];
  477.     ">"        BEGIN(SECT2); return '>';
  478.     ">"/^        BEGIN(CARETISBOL); return '>';
  479.     {SCNAME}    RETURNNAME;
  480.     .        {
  481.             format_synerr( _( "bad <start condition>: %s" ),
  482.                 yytext );
  483.             }
  484. }
  485.  
  486. <CARETISBOL>"^"        BEGIN(SECT2); return '^';
  487.  
  488.  
  489. <QUOTE>{
  490.     [^"\n]        RETURNCHAR;
  491.     \"        BEGIN(SECT2); return '"';
  492.  
  493.     {NL}        {
  494.             synerr( _( "missing quote" ) );
  495.             BEGIN(SECT2);
  496.             ++linenum;
  497.             return '"';
  498.             }
  499. }
  500.  
  501.  
  502. <FIRSTCCL>{
  503.     "^"/[^-\]\n]    BEGIN(CCL); return '^';
  504.     "^"/("-"|"]")    return '^';
  505.     .        BEGIN(CCL); RETURNCHAR;
  506. }
  507.  
  508. <CCL>{
  509.     -/[^\]\n]    return '-';
  510.     [^\]\n]        RETURNCHAR;
  511.     "]"        BEGIN(SECT2); return ']';
  512.     .|{NL}        {
  513.             synerr( _( "bad character class" ) );
  514.             BEGIN(SECT2);
  515.             return ']';
  516.             }
  517. }
  518.  
  519. <FIRSTCCL,CCL>{
  520.     "[:alnum:]"    BEGIN(CCL); return CCE_ALNUM;
  521.     "[:alpha:]"    BEGIN(CCL); return CCE_ALPHA;
  522.     "[:blank:]"    BEGIN(CCL); return CCE_BLANK;
  523.     "[:cntrl:]"    BEGIN(CCL); return CCE_CNTRL;
  524.     "[:digit:]"    BEGIN(CCL); return CCE_DIGIT;
  525.     "[:graph:]"    BEGIN(CCL); return CCE_GRAPH;
  526.     "[:lower:]"    BEGIN(CCL); return CCE_LOWER;
  527.     "[:print:]"    BEGIN(CCL); return CCE_PRINT;
  528.     "[:punct:]"    BEGIN(CCL); return CCE_PUNCT;
  529.     "[:space:]"    BEGIN(CCL); return CCE_SPACE;
  530.     "[:upper:]"    BEGIN(CCL); return CCE_UPPER;
  531.     "[:xdigit:]"    BEGIN(CCL); return CCE_XDIGIT;
  532.     {CCL_EXPR}    {
  533.             format_synerr(
  534.                 _( "bad character class expression: %s" ),
  535.                     yytext );
  536.             BEGIN(CCL); return CCE_ALNUM;
  537.             }
  538. }
  539.  
  540. <NUM>{
  541.     [[:digit:]]+    {
  542.             yylval = myctoi( yytext );
  543.             return NUMBER;
  544.             }
  545.  
  546.     ","        return ',';
  547.     "}"        BEGIN(SECT2); return '}';
  548.  
  549.     .        {
  550.             synerr( _( "bad character inside {}'s" ) );
  551.             BEGIN(SECT2);
  552.             return '}';
  553.             }
  554.  
  555.     {NL}        {
  556.             synerr( _( "missing }" ) );
  557.             BEGIN(SECT2);
  558.             ++linenum;
  559.             return '}';
  560.             }
  561. }
  562.  
  563.  
  564. <PERCENT_BRACE_ACTION>{
  565.     {OPTWS}"%}".*        bracelevel = 0;
  566.  
  567.     <ACTION>"/*"        ACTION_ECHO; yy_push_state( COMMENT );
  568.  
  569.     <CODEBLOCK,ACTION>{
  570.         "reject"    {
  571.             ACTION_ECHO;
  572.             CHECK_REJECT(yytext);
  573.             }
  574.         "yymore"    {
  575.             ACTION_ECHO;
  576.             CHECK_YYMORE(yytext);
  577.             }
  578.     }
  579.  
  580.     {NAME}|{NOT_NAME}|.    ACTION_ECHO;
  581.     {NL}        {
  582.             ++linenum;
  583.             ACTION_ECHO;
  584.             if ( bracelevel == 0 ||
  585.                  (doing_codeblock && indented_code) )
  586.                 {
  587.                 if ( doing_rule_action )
  588.                     add_action( "\tYY_BREAK\n" );
  589.  
  590.                 doing_rule_action = doing_codeblock = false;
  591.                 BEGIN(SECT2);
  592.                 }
  593.             }
  594. }
  595.  
  596.  
  597.     /* Reject and YYmore() are checked for above, in PERCENT_BRACE_ACTION */
  598. <ACTION>{
  599.     "{"        ACTION_ECHO; ++bracelevel;
  600.     "}"        ACTION_ECHO; --bracelevel;
  601.     [^[:alpha:]_{}"'/\n]+    ACTION_ECHO;
  602.     {NAME}        ACTION_ECHO;
  603.     "'"([^'\\\n]|\\.)*"'"    ACTION_ECHO; /* character constant */
  604.     \"        ACTION_ECHO; BEGIN(ACTION_STRING);
  605.     {NL}        {
  606.             ++linenum;
  607.             ACTION_ECHO;
  608.             if ( bracelevel == 0 )
  609.                 {
  610.                 if ( doing_rule_action )
  611.                     add_action( "\tYY_BREAK\n" );
  612.  
  613.                 doing_rule_action = false;
  614.                 BEGIN(SECT2);
  615.                 }
  616.             }
  617.     .        ACTION_ECHO;
  618. }
  619.  
  620. <ACTION_STRING>{
  621.     [^"\\\n]+    ACTION_ECHO;
  622.     \\.        ACTION_ECHO;
  623.     {NL}        ++linenum; ACTION_ECHO;
  624.     \"        ACTION_ECHO; BEGIN(ACTION);
  625.     .        ACTION_ECHO;
  626. }
  627.  
  628. <COMMENT,ACTION,ACTION_STRING><<EOF>>    {
  629.             synerr( _( "EOF encountered inside an action" ) );
  630.             yyterminate();
  631.             }
  632.  
  633.  
  634. <SECT2,QUOTE,FIRSTCCL,CCL>{ESCSEQ}    {
  635.             yylval = myesc( (Char *) yytext );
  636.  
  637.             if ( YY_START == FIRSTCCL )
  638.                 BEGIN(CCL);
  639.  
  640.             return CHAR;
  641.             }
  642.  
  643.  
  644. <SECT3>{
  645.     .*(\n?)        ECHO;
  646.     <<EOF>>        sectnum = 0; yyterminate();
  647. }
  648.  
  649. <*>.|\n            format_synerr( _( "bad character: %s" ), yytext );
  650.  
  651. %%
  652.  
  653.  
  654. int yywrap()
  655.     {
  656.     if ( --num_input_files > 0 )
  657.         {
  658.         set_input_file( *++input_files );
  659.         return 0;
  660.         }
  661.  
  662.     else
  663.         return 1;
  664.     }
  665.  
  666.  
  667. /* set_input_file - open the given file (if NULL, stdin) for scanning */
  668.  
  669. void set_input_file( char *file )
  670.     {
  671.     if ( file && strcmp( file, "-" ) )
  672.         {
  673.         infilename = copy_string( file );
  674.         yyin = fopen( infilename, "r" );
  675.  
  676.         if ( yyin == NULL )
  677.             lerrsf( _( "can't open %s" ), file );
  678.         }
  679.  
  680.     else
  681.         {
  682.         yyin = stdin;
  683.         infilename = copy_string( "<stdin>" );
  684.         }
  685.  
  686.     linenum = 1;
  687.     }
  688.  
  689.  
  690. /* Wrapper routines for accessing the scanner's malloc routines. */
  691.  
  692. void *flex_alloc( size_t size )
  693.     {
  694.     SpinCursor(32);
  695.     return (void *) malloc( size );
  696.     }
  697.  
  698. void *flex_realloc( void *ptr, size_t size )
  699.     {
  700.     SpinCursor(32);
  701.     return (void *) realloc( ptr, size );
  702.     }
  703.  
  704. void flex_free( void *ptr )
  705.     {
  706.     SpinCursor(32);
  707.     if ( ptr )
  708.         free( ptr );
  709.     }
  710.